#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef WIN32
#  include <unistd.h>
#endif
#include <curl/multi.h>

static const char *urls[] = {
	"http://hzbank.com.cn/index.shtml",
};

#define MAX 10 /* number of simultaneous transfers */
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */

static size_t cb(char *d, size_t n, size_t l, void *p)
{
	/* take care of the data here, ignored in this example */
	(void)d;
	(void)p;
	printf("%s\n", d);
	return n*l;
}

static size_t gethead(char *d, size_t n, size_t l, void *p)
{
	/* take care of the data here, ignored in this example */
	(void)d;
	(void)p;
	printf("%s\n", d);
	return n*l;
}

static void init(CURLM *cm, int i)
{
	CURL *eh = curl_easy_init();

	curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, NULL);
	//curl_easy_setopt(eh, CURLOPT_WRITEDATA, NULL);
	curl_easy_setopt(eh, CURLOPT_HEADERFUNCTION, NULL);
	curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
	curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
	curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
	curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
	curl_easy_setopt(eh, CURLOPT_NOSIGNAL, 1L);
	/* 整个网页的的超时时间为60s */
	curl_easy_setopt(eh, CURLOPT_TIMEOUT, 60);  
	/* 连接时间不能超过4s */
	curl_easy_setopt(eh, CURLOPT_CONNECTTIMEOUT, 4);  
	curl_easy_setopt(eh, CURLOPT_FORBID_REUSE, 1L);
	curl_multi_add_handle(cm, eh);


}

int main(void)
{
	CURLM *cm;
	CURLMsg *msg;
	long L;
	unsigned int C=0;
	int M, Q, U = -1; fd_set R, W, E;
	struct timeval T;
	cm = curl_multi_init();

	CURL *eh = curl_easy_init();
	curl_multi_add_handle(cm, eh);
	eh = NULL;	
	curl_easy_cleanup(eh);
	curl_multi_remove_handle(cm, eh);

	curl_global_init(CURL_GLOBAL_ALL);

	init(cm, 0);
	/* we can optionally limit the total amount of connections this multi handle uses */
	curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS /* Added in 7.16.3 */, (long)MAX);

	while (1) {
		/* 将running_handles,复制给U */
		curl_multi_perform(cm, &U);
		if (U) {
			FD_ZERO(&R);
			FD_ZERO(&W);
			FD_ZERO(&E);
			/* 会设置最大的fd到M中 */
			if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
				fprintf(stderr, "E: curl_multi_fdset\n");
				return EXIT_FAILURE;
			}

			if (curl_multi_timeout(cm, &L)) {
				fprintf(stderr, "E: curl_multi_timeout\n");
				return EXIT_FAILURE;
			}

			if (L == -1)
				L = 100;
			
			if (M == -1) {
				sleep(L / 1000);
			} 
			else	
			{
				/* 最多1s */
				if (L > 1000)
					L = 1000;
				T.tv_sec = L/1000;
				T.tv_usec = (L%1000)*1000;
				/* 碰到google这样的网站就死在这里了 */
				if (0 > select(M+1, &R, &W, &E, &T)) {
					fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n", M+1, L, errno, strerror(errno));
					return EXIT_FAILURE;
				}
			}
		}

		while ((msg = curl_multi_info_read(cm, &Q))) {
			if (msg->msg == CURLMSG_DONE) {
				char *url;
				CURL *e = msg->easy_handle;
				curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
				FILE *fp = fopen("aaa", "a+");
				fprintf(fp, "R: %d - %s <%s>\n", msg->data.result, curl_easy_strerror(msg->data.result), url);
				fclose(fp);
				fprintf(stderr, "R: %d - %s <%s>\n", msg->data.result, curl_easy_strerror(msg->data.result), url);
				exit(1);	
				curl_multi_remove_handle(cm, e);
				curl_easy_cleanup(e);
			}
			else {
				CURL *e = msg->easy_handle;
				fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
				FILE *fp = fopen("aaa", "a+");
				fprintf(fp, "E: CURLMsg (%d)\n", msg->msg);
				fclose(fp);
				curl_multi_remove_handle(cm, e);
				curl_easy_cleanup(e);
			}
		}
	}

	curl_multi_cleanup(cm);
	curl_global_cleanup();

	return EXIT_SUCCESS;
}

